package com.itextpdf.local.ess.Revision;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;

import static com.itextpdf.local.ess.FileUtils.*;

public class RevisionUtils {

    public static void main(String[] args) {
        byte[] file = File2byte("D:\\demo.pdf");
        byte[] file1 = new byte[0];
        try {
            getRevisionInfo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
//        byte2File(file1,"D:\\demo1.pdf");
    }
    public static List<RevisionInfo> getRevisionInfo(byte[] file) throws IOException {
        List<RevisionInfo> revisionInfos = new ArrayList<>();
        PdfReader reader = new PdfReader(file);
        AcroFields fields = reader.getAcroFields();
        ArrayList<String> names = fields.getSignatureNames();
        int total = fields.getTotalRevisions();
        for (String name: names) {
            RevisionInfo revisionInfo = new RevisionInfo();
            revisionInfo.setRevision(fields.getRevision(name));
            revisionInfo.setSignatureName(name);
            revisionInfo.setTotalRevisions(total);
            revisionInfos.add(revisionInfo);
        }
        return revisionInfos;
    }

    /**
     * 回退到上一版本
     * @param file
     * @return
     * @throws IOException
     * @throws GeneralSecurityException
     */
    public static byte[] switchToPreviousRevision(byte[] file) throws IOException, GeneralSecurityException {
        String signatureName ="";
        byte[] result;
        PdfReader reader = new PdfReader(file);
        AcroFields fields = reader.getAcroFields();
        ArrayList<String> names = fields.getSignatureNames();
        PdfDictionary dss = reader.getCatalog().getAsDict(PdfName.DSS);

        if (names.size() > 1) {
            //签章数量大于等于2时，执行回退版本
            signatureName = names.get(names.size() - 2);
            result = inputStream2byte(fields.extractRevision(signatureName));
        }else if(names.size() == 1){
            //签章数量等于1时，执行
            fields.removeField(signatureName);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            PdfStamper stamper = null;
            try {
                stamper = new PdfStamper(reader, os);
                stamper.close();
                reader.close();
                os.close();
            } catch (DocumentException e) {
                e.printStackTrace();
            }
            result =  os.toByteArray();
        }else {
            result = null;
            //LOGGER.info("No signatures in revision");
        }
//        Calendar cal = pkcs7.getTimeStampDate();
//        if (cal == null) {
//            cal = pkcs7.getSignDate();
//        }
//        // TODO: get date from signature
//        signDate = cal.getTime();
        return result;
    }

    /**
     * 回退到指定版本(指定ID)
     * @param file
     * @param signatureName
     * @return
     * @throws IOException
     * @throws GeneralSecurityException
     */
    public static byte[] switchToRevision(byte[] file,String signatureName) throws IOException, GeneralSecurityException {
        byte[] result;
        PdfReader reader = new PdfReader(file);
        AcroFields fields = reader.getAcroFields();
        ArrayList<String> names = fields.getSignatureNames();
        if(!names.contains(signatureName)){
            return null;
        }
        int revision  = fields.getRevision(signatureName);
        if (revision > 1) {
            result = inputStream2byte(fields.extractRevision(names.get(revision-2)));
        }else if(revision == 1){
            result = inputStream2byte(fields.extractRevision(signatureName));

            PdfReader reader1 = new PdfReader(result);
            AcroFields fields1 = reader1.getAcroFields();
            //签章数量等于1时，执行
            fields1.removeField(signatureName);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            PdfStamper stamper = null;
            try {
                stamper = new PdfStamper(reader1, os);
                stamper.close();
            } catch (DocumentException e) {
                e.printStackTrace();
            }
            result =  os.toByteArray();
            reader1.close();
            os.close();
        }else {
            result = null;
        }

        reader.close();
        return result;
    }
}
